Aujourd’hui on apprend ce qu’est le logiciel d’analyse statistique R.
Les materiaux sont adaptés des ressources excellents de CSBQ:
https://r.qcbs.ca/workshop01/book-fr/index.html
https://r.qcbs.ca/workshop02/book-fr/index.html
https://r.qcbs.ca/workshop03/book-fr/index.html
Ça veut dire qu’on peut utiliser notre code pour répéter nos analyses et on arrive à la même solution. On peut egalement partager notre code pour que les autres puissent répéter les analyses.
Pourquoi est-ce que c’est utile? Imagine tu travailles dans un laboratoire qui realise un service de protéomique. Pour chaque groupe d’échantillons tu dois préparer des statistiques et des figures et tu reçevois 100 échantillons par semaine!
Avec R, c’est facile d’ajouter des données et refaire une analyse! On peut également automatiser les analyses. (Exemple)
Il faut installer le logiciel R et le logiciel RStudio. RStudio n’est pas strictement obligatoire, mais l’experience d’apprentisage et de l’utilisation est plus agréable avec RStudio.
Pour obtenir le logiciel R: http://www.r-project.org/
Pour obtenir R Studio: https://posit.co/download/rstudio-desktop/
Ouvrez RStudio et explorez.
On y trouve plusieurs onglets et fenêtres. La console est pour executer le code. Tapez et appuyer sur “enter” pour que le code soit exécuté dans la console.
Exemple: Faites des calculs
1 + 1
## [1] 2
2 - 1
## [1] 1
2 * 2
## [1] 4
8 / 2
## [1] 4
2 ^ 3
## [1] 8
Normalement, on n’utilise pas la console pour taper et executer le code, parce que ce n’est pas enregistré. À la place, on utilise les scripts pour écrire et enregistrer le code.
Ouvrez un nouveau R script
Dans le script on peut écrire le code et l’executer en appuyant sur
Alt + Enter (ou Cmd + Enter). Les lignes qui
debutent par # sont ignorées, donc c’est très utile pour
faire des commentaires! Laissant les commentaires pour annoter votre
code est extrêmement important!
Les objets
R est un langage de programmation par objet (object-oriented programming language). Ça signifie qu’on peut allouer un nom à des valeurs qu’on a créées afin de les enregistrer dans un espace de travail. Un objet est composé de trois parties : 1) une valeur d’intérêt, 2) un identifiant et 3) l’opérateur d’assignation.
<-) et est utilisé afin de lier la valeur d’intérêt à
son identifiant.Exemple:
x <- 3 * (14 / 2)
Dans cet exemple, 3 * (14 / 2) est la valeur qu’on
souhaite enregistrer en tant qu’objet. L’identifiant "x" est assigné à
cette valeur. En tapant x à la console ou en executant dans
le script, R retourne la valeur du calcul:
x
## [1] 21
Faites attention: R fait la différence entre les lettres miniscules et majuscules:
X
## Error in eval(expr, envir, enclos): object 'X' not found
Nom:
var n’est pas très instructif._ pour séparer les
mots d’un nom ou essayez d’être constant!c ou table)Espace:
=,
+, -, <-, etc.) pour rendre le
code plus lisibleLe logiciel R est un outil très puissant pour l’analyse des données. Les données existent sous plusieurs formes, mais peuvent être regroupées en catégories distinctes. R classifie les données selon la nature des valeurs contenues dans un objet. La figure suivante illustre les types de données couramment rencontrés dans R.
Types de structures de données en R: le vecteur
Le premier type d’objet est le vecteur. C’est un des
objets les plus communs dans R. Un vecteur est une entité constituée
d’une liste de valeurs semblables. Toutes les valeurs d’un vecteur
doivent avoir le même mode (ou classe). Les principaux modes dans R sont
numérique, caractère et
logique. Les vecteurs numériques sont seulement
composés de nombres. Les vecteurs de caractères sont généralement
composés de chaînes de caractères ou d’un mélange de chaînes de
caractères et de valeurs numériques et logiques. Il est absolument
nécessaire d’utiliser les guillemets " " afin de délimiter
les chaînes de caractères. Les vecteurs logiques sont composés des mots
TRUE et FALSE seulement.
Regardons maintenant comment générer différents types de vecteurs (i.e. de différents modes).
#Créez un vecteur numérique avec la fonction c (qui signifie combiner ou concaténer).
num_vecteur <- c(1, 4, 3, 98, 32, -76, -4)
num_vecteur
## [1] 1 4 3 98 32 -76 -4
#Créez un vecteur de caractères. N’oubliez pas les guillemets !
car_vecteur <- c("bleu", "rouge", "vert")
car_vecteur
## [1] "bleu" "rouge" "vert"
#Créez un vecteur logique ou booléen. N’utilisez pas les guillemets sinon R va considérer les éléments
#comme des chaînes de caractères.
bool_vecteur <- c(TRUE, TRUE, FALSE)
bool_vecteur
## [1] TRUE TRUE FALSE
#C’est aussi possible d’utiliser les abréviations pour les vecteurs logiques.
bool_vecteur2 <- c(T, T, F)
bool_vecteur2
## [1] TRUE TRUE FALSE
Pourquoi est-ce que les vecteurs sont utiles? les vecteurs peuvent être utilisés dans des calculs. La seule différence est que, lorsqu’un vecteur a plus d’un élément, l’opération est appliquée à tous les éléments du vecteur. L’exemple suivant clarifie ceci.
#Créez deux vecteurs numériques.
x <- 1:5
# Le symbole '':'', lorsqu’utilisé avec des chiffres, est l’opérateur de séquence.
# Ça indique à R de créer une série qui augmente de 1.
# C’est équivalent à écrire x <- c(1, 2, 3, 4, 5)
# Une autre façon équivalente est : x <- c(1:5).
y <- 6
# Faisons la somme des deux vecteurs.
# 6 est ajouté à tous les éléments du vecteur x.
x + y
## [1] 7 8 9 10 11
# Multiplions x par y.
x * y
## [1] 6 12 18 24 30
Types de structures de données en R: le data frame
Un autre type d’objet couramment utilisé en biologie, écologie et anthropologie est le data frame (c-à-d. tableau de données). Un data frame est un groupe de vecteurs de la même longueur (i.e. avec le même nombre d’éléments). Les variables sont toujours représentées en colonnes et les observations, cas, individus, sites ou répétitions sont toujours représentés en lignes. Un data frame peut être composé de plusieurs modes, mais une colonne doit toujours contenir le même mode. C’est sous ce format que la plupart des données écologiques sont enregistrées. L’exemple suivant présente un jeu de données fictif représentant quatre sites où le pH du sol et le nombre d’espèces ont été mesurés. On y trouve également une colonne de traitement (fertilisé ou non). Regardons plus en détail comment créer un tel tableau de données.
| site_id | pH_sol | num_sp | traitement |
|---|---|---|---|
| A1.01 | 5.6 | 17 | Fertilisé |
| A1.02 | 7.3 | 23 | Fertilisé |
| B1.01 | 4.1 | 15 | Non Fertilisé |
| B1.02 | 6.0 | 17 | Non Fertilisé |
N. B. Les noms des colonnes et leur contenu n’ont ni accent, ni d’espace, ni caractères spéciaux puisque R préfère une seule suite de caractères comme titre. Ainsi, num_sp représente bien ‘Nombre d’espèces’, mais R préfère la forme ‘num_sp’. Il en va de même pour le contenu du tableau (pas ‘Fertilisé’, mais bien ‘Fert’).
# On commence par créer les vecteurs.
site_id <- c("A1.01", "A1.02", "B1.01", "B1.02") # l'identifiant du site
pH_sol <- c(5.6, 7.3, 4.1, 6.0) #la mesure du pH du sol à chaque site
num_sp <- c(17, 23, 15, 7) #le nombre d'espèces observées
traitement <- c("Fert", "Fert", "Non_fert", "Non_fert") #traitement appliqué
# On peut grouper tous ces vecteurs en un data frame avec la fonction data.frame().
mon_df <- data.frame(site_id, pH_sol, num_sp, traitement)
# On l’affiche à la console!
mon_df
## site_id pH_sol num_sp traitement
## 1 A1.01 5.6 17 Fert
## 2 A1.02 7.3 23 Fert
## 3 B1.01 4.1 15 Non_fert
## 4 B1.02 6.0 7 Non_fert
Les autres types d’objets pour stocker des données qu’on retrouve dans R sont les matrices, les tableaux (i.e. array en anglais) et les listes. Une matrice est très similaire à un data frame à l’exception que toutes les cellules de la matrice doivent être du même mode. Un array est similaire à une matrice, mais peut avoir plus de deux dimensions. Les arrays sont surtout utilisés pour des calculs avancés tels que des simulations numériques et des tests de permutations. Une liste est un groupement de plusieurs types d’objets différents. Par exemple, une liste pourrait comprendre un vecteur, un tableau de données et une matrice au sein du même objet.
Lorsqu’on tape le nom d’un objet dans la console, R retourne l’objet
en entier. Par contre, ce n’est pas pratique si l’objet est, par
exemple, une énorme base de données avec des millions de lignes. Ça peut
rapidement devenir difficile d’identifier des éléments précis d’un
objet. R nous permet d’extraire certaines parties d’un objet en indexant
ce dernier. Il suffit de spécifier la position des valeurs à l’intérieur
d’un objet qu’on souhaite extraire à l’aide des crochets
[ ]. Le code suivant illustre le concept d’indexation des
vecteurs.
# Créons tout d’abord un vecteur numérique et un vecteur de caractères.
# Ce n’est pas nécessaire de faire cette étape si vous l’avez déjà fait dans un exercice précédent.
impair <- c(1, 3, 5, 7, 9)
# Extrayons le deuxième élément du vecteur numérique.
impair[2]
## [1] 3
# Extrayons les 2ème et 4ème éléments du vecteur numérique.
impair[c(2, 4)]
## [1] 3 7
# Extrayons tous les éléments du vecteur numérique sauf les deux premières.
impair[c(-1, -2)]
## [1] 5 7 9
# Si nous sélectionnons une position qui n'existe pas dans le vecteur numérique.
impair[c(1,6)]
## [1] 1 NA
Il n’y a pas de sixième valeur dans ce vecteur, donc R retourne une valeur nulle (i.e. NA). NA signifie ‘Not available’.
# Nous pouvons également utiliser des conditions pour sélectionner des valeurs.
impair[impair > 4]
## [1] 5 7 9
# Nous pouvons procéder de même sur les vecteurs de caractère
# Extraire tous les éléments correspondant exactement à « bleu » du vecteur de caractères.
# Prenez note de l’utilisation du double signe d’égalité ==.
car_vecteur[car_vecteur == "rouge"]
## [1] "rouge"
#Pour chaque élément du vecteur `car_vecteur`, R vérifie si cet élément est exactement égal à « bleu » ou non et retourne une réponse (TRUE ou FALSE)
car_vecteur == "rouge"
## [1] FALSE TRUE FALSE
L’indexation des data frames est similaire à celle des vecteurs, mais il est généralement nécessaire de spécifier deux dimensions : le numéro de ligne et de colonne. Pour ce faire, la syntaxe dans R est :
data frame[numéro de ligne, numéro de colonne].
Voici quelques exemples d’indexation de data frames. Prenez note que les quatre premières opérations sont également valides pour les matrices.
# Réutilisons le data frame créé précédemment (mon_df)
# Extrayons la première ligne du data frame.
mon_df[1, ]
## site_id pH_sol num_sp traitement
## 1 A1.01 5.6 17 Fert
# Extrayons la troisième colonne du data frame.
mon_df[, 3]
## [1] 17 23 15 7
# Notez qu'un index vide sélectionne toutes les valeurs
# Extrayons le deuxième élément de la quatrième colonne du data frame.
mon_df[2, 4]
## [1] "Fert"
# Extrayons les lignes 2 et 4 du data frame.
mon_df[c(2,4), ]
## site_id pH_sol num_sp traitement
## 2 A1.02 7.3 23 Fert
## 4 B1.02 6.0 7 Non_fert
# Extrayons la colonne « site_id » en référant directement à son nom.
# Le signe de dollar ($) permet une telle opération !
mon_df$site_id
## [1] "A1.01" "A1.02" "B1.01" "B1.02"
# Extrayons la deuxième valeur de la colonne « site_id »
mon_df$site_id[2]
## [1] "A1.02"
# Extrayons les variables « site_id » et « pH_sol ».
mon_df[,c("site_id","pH_sol")]
## site_id pH_sol
## 1 A1.01 5.6
## 2 A1.02 7.3
## 3 B1.01 4.1
## 4 B1.02 6.0
Les packages (bibliothèques pour être rigoureux) sont des regroupements de fonctions et de jeux de données partageant un thème similaire, e.g. statistiques, analyse spatiale, visualisation…
Tout le monde peut développer des packages et les rendre disponibles aux autres utilisateurs de R.
Les packages sont généralement disponibles via le Comprehensive R Archive Network (CRAN) http://cran.r-project.org/web/packages/.
Actuellement, plus de 18000 packages sont disponibles librement.
Pour installer des packages dans R, il suffit d’utiliser la fonction install.packages()
Il est nécessaire d’installer un package une seule fois, même si des mises à jours régulières sont recommandées. Cependant, pour utiliser une fonction se trouvant au sein d’un package, il ne suffit pas de simplement installer le package. Il faut également utiliser la fonction library() à chaque début de session R pour “charger” le package.
Installons les packages dont on a besoin aujourd’hui:
install.packages(c("ggplot2", "tidyr", "dplyr", "palmerpenguins", "lubridate"))
Vous avez appris comment créer un dataframe “à la main” mais normalement, ce n’est pas pratique. Fréquemment, les données sont dans les fichiers comme excel ou csv puis c’est plus facile de les importer directement.
Vous devez indiquer à R le répertoire où se trouvent les fichiers de données afin de les charger. Vous pouvez voir quel répertoire R utilise avec la fonction getwd()”
getwd() # Cette commande vous indique le répertoire dans lequel vous vous trouvez.
## [1] "/Users/mjaniak/Documents/UdeM/R"
Lorsque vous chargez un script, R définit le répertoire de travail comme étant le dossier qui contient le script.
Afin de spécifier le chemin d’accès du répertoire avec la fonction setwd(), utilisez le “/” pour séparer les dossiers, sous-dossiers et noms de fichiers. Vous pouvez aussi cliquer sur session / Définir le répertoire / Choisir le répertoire.
La fonction dir() affiche le contenu du répertoire de
travail.
dir() # Cette commande vous indique le contenu du répertoire dans lequel vous vous trouvez.
Vous pouvez vérifier:
Utilisez la fonction read.csv() pour importer des
données provenant d’un fichier .csv dans R.
CO2<-read.csv("CO2_good.csv", header = TRUE)
# Cette commande crée un objet nommé CO2 en chargeant les données
# du fichier nommé "CO2_good.csv".
Cette commande spécifie que vous créez un objet nommé “CO2” en lisant un fichier .csv nommé “CO2_good.csv”.
L’argument header permet de spécifier si la première
ligne du fichier contient le nom des colonnes. Inscrire
header=TRUE indique à R que la première ligne du tableau
contient les noms des colonnes.
Le jeu de données “CO2” contient des mesures répétées d’absorption de CO2 prises sur six plantes du Québec et six plantes du Mississippi à différentes concentrations de CO2 ambiant. La moitié des plantes de chaque région a subi un traitement de refroidissement la veille du début de l’expérience.
Rappelez-vous de la section “Indexer un data frame”. Utilisez les
operations afin d’explorer CO2.
On peut changer le nom de variables (colonnes) dans R.
# afficher les noms des colonnes présents dans le jeu de données:
colnames(CO2)
## [1] "Plant" "Type" "Treatment" "conc" "uptake"
# changer des noms anglais à des noms français:
colnames(CO2) <- c("Plante", "Categorie", "Traitement", "conc", "absortion")
On peut facilement créer et produire des nouvelles variables. Par
exemple, la fonction paste() permet la concaténation de
chaînes de caractères et de variables.
# Créer un ID unique pour les échantillons avec la fonction
# ''paste()'' Consultez ?paste et ?paste0 N'oubliez pas
# d'utiliser '' pour les chaînes de caractères
CO2$uniqueID <- paste0(CO2$Plante, "_", CO2$Categorie,
"_", CO2$Traitement)
# Observer les résultats
CO2
On peut aussi créer des nouvelles variables à partir de chiffres et d’opérations mathématiques!
# Standardizer la variable 'absortion' en valeurs relatives
CO2$absortionRel = CO2$absortion/max(CO2$absortion)
# Observer les résultats
head(CO2$absortionRel)
## [1] 0.3516484 0.6681319 0.7648352 0.8175824 0.7758242 0.8615385
Pour faire une première exploration de données, on peut rapidement
calculer des statistiques de base avec la fonction
summary().
summary(CO2)
## Plante Categorie Traitement conc absortion
## Qn1 : 7 Quebec :42 nonchilled:42 Min. : 95 Min. : 7.70
## Qn2 : 7 Mississippi:42 chilled :42 1st Qu.: 175 1st Qu.:17.90
## Qn3 : 7 Median : 350 Median :28.30
## Qc1 : 7 Mean : 435 Mean :27.21
## Qc3 : 7 3rd Qu.: 675 3rd Qu.:37.12
## Qc2 : 7 Max. :1000 Max. :45.50
## (Other):42
## absortionRel
## Min. :0.1692
## 1st Qu.:0.3934
## Median :0.6220
## Mean :0.5981
## 3rd Qu.:0.8159
## Max. :1.0000
##
Plusieurs fonctions intégrées à R vous permettent d’obtenir de
l’information supplémentaire sur vos données. Les fonctions
mean(), sd(), hist(), et
print() sont couramment utilisées.
# Calculer la moyenne et l'écart type des données dans la colonne "conc" de l'objet CO2
meanConc<-mean(CO2$conc) # Calcule la moyenne de la colonne "conc" de l'objet "CO2"
sdConc<-sd(CO2$conc) # Calcule l'écart-type de la colonne "conc"
# print() sort une valeure dans la console R
print(paste("la concentration moyenne est:", meanConc))
## [1] "la concentration moyenne est: 435"
print(paste("l'écart type de la concentration est:", sdConc))
## [1] "l'écart type de la concentration est: 295.924119222056"
# Produisez un histogramme to explore the distribution of "uptake"
hist(CO2$absortion)
# Augmenter le nombre de classes pour mieux observer la distribution
hist(CO2$absortion, breaks = 40)
La réorganisation permet de modifier la structure des données tout en préservant l’information contenue dans le jeu de données. Plusieurs fonctions dans R exigent ou fonctionnent mieux avec une structure de données qui n’est pas nécessairement propice à la lecture par l’oeil humain.
En comparaison à l’agrégation, où plusieurs cellules sont regroupées
pour créer un nouveau jeu de données (e.g. tableau des moyennes de
plusieurs variables), la réorganisation maintient le même nombre de
cellules. Le paquet tidyr permet de réorganiser nos jeu de
données dans un format idéal pour nos tâches en aval, et ce à l’aide
d’une syntaxe simple et logique.
tidyr est un paquet qui réorganise la structure de jeux
de données.
pivot_longer()pivot_wider()separate() et de son inverse, unite()Voici un aide-mémoire (en anglais) pour faciliter la
manipulation de jeux de données avec tidyr et
dplyr: https://www.rstudio.com/wp-content/uploads/2015/02/data-wrangling-cheatsheet.pdf
Un jeu de données en largeur contient une colonne pour chaque variable ou facteur inclus dans les données. Une rangée peut alors comprendre plusieurs observations différentes.
Un jeu de données en longueur contient une colonne
par variable, où chaque rangée s’agit d’une observation unique. Le
format “long” est plus “propre” (tidy en anglais), parce que
les données sont plus facilement interprétées par R pour
nos visualisations et nos analyses.
Le format de vos données dépend de vos besoins d’analyse et de
visualisation, mais certains paquets et fonctions, incluant
dplyr, lm(), glm(), et
gam(), nécessitent des données en longueur. Le paquet
ggplot2 peut utiliser des données en largeur pour des
visualisations simples, mais fonctionne mieux avec des données en
longueur pour des visualisations plus complexes (exemple à venir).
De plus, les données en format long peuvent être agrégées et réorganisées en format large afin de produire des résumés ou de vérifier si un jeu de données est équilibré (i.e. avec le même nombre d’observations par traitement).
On peut utiliser le paquet tidyr pour manipuler la
structure d’un jeu de données en préservant toutes les informations
d’origine à l’aide des fonctions suivantes:
Supposons que vous envoyez votre assistant de terrain pour faire la collecte de données des dimensions de plusieurs arbres sur un site de recherche, soit le diamètre à la hauteur de la poitrine (DHP) et la hauteur. Il/elle revient avec un jeu de données en format “dégât” (format large):
large <- data.frame(Species = c("Chêne", "Orme", "Frêne"),
DHP = c(12, 20, 13),
Haut = c(56, 85, 55))
large
## Species DHP Haut
## 1 Chêne 12 56
## 2 Orme 20 85
## 3 Frêne 13 55
Utilisons la fonction pivot_longer() pour “rassembler”
nos données en longueur. pivot_longer() prend plusieurs
colonnes et les empile dans deux colonnes: une colonne spécifiant la
variable mesurée, et l’autre spécifiant la mesure associée.
La fonction pivot_longer() prend au moins 3
arguments:
Voici une démonstration avec le jeu de données large
utilisé précédemment, contenant les dimensions d’arbres:
# Rassembler les colonnes en rangées d'observations uniques avec tidyr
library(tidyr)
pivot_longer(data = large,
cols = c("DHP", "Haut"),
names_to = "dimension",
values_to = "cm")
## # A tibble: 6 × 3
## Species dimension cm
## <chr> <chr> <dbl>
## 1 Chêne DHP 12
## 2 Chêne Haut 56
## 3 Orme DHP 20
## 4 Orme Haut 85
## 5 Frêne DHP 13
## 6 Frêne Haut 55
Le jeu de données “airquality” est un data frame qui est déjà disponbible dans R:
data("airquality")
head(airquality)
## Ozone Solar.R Wind Temp Month Day
## 1 41 190 7.4 67 5 1
## 2 36 118 8.0 72 5 2
## 3 12 149 12.6 74 5 3
## 4 18 313 11.5 62 5 4
## 5 NA NA 14.3 56 5 5
## 6 28 NA 14.9 66 5 6
Le but est de rassembler les colonnes Ozone,
Solar.R, Wind et Temp dans une
seule colonne (“variable”) et leur données dans une autre colonne nommée
“value”:
air.long <- pivot_longer(airquality,
cols = c("Ozone", "Solar.R", "Wind", "Temp"),
names_to = c("variable"),
values_to = c("value"))
head(air.long)
## # A tibble: 6 × 4
## Month Day variable value
## <int> <int> <chr> <dbl>
## 1 5 1 Ozone 41
## 2 5 1 Solar.R 190
## 3 5 1 Wind 7.4
## 4 5 1 Temp 67
## 5 5 2 Ozone 36
## 6 5 2 Solar.R 118
Souvent, on doit faire appel à une gamme d’outils complexes pour
manipuler nos jeux de données. La mission de dplyr est de
simplifier nos tâches de manipulation en regroupant toutes les
opérations communes sous un même toit. Le résultat est une collection de
fonctions ayant une syntaxe simple qu’on peut exécuter à l’aide de
“verbes” (ou fonctions) intuitifs.
Au coeur du paquet dplyr, on retrouve des “verbes”
essentiels qui nous permettent d’accomplir la manipulation de données.
Voici 4 verbes qui exécutent les opérations les plus communes:
select() : sélectionne des colonnes dans un jeu de
donnéesfilter() : filtre des rangées suivant les critères
spécifiésarrange() : trie les données d’une colonne en ordre
croissant ou décroissantmutate() : crée une nouvelle colonne de données (ou
transforme une colonne existante)Ces opérations deviennent particulièrement puissants quand ils sont
reliés par le “pipe” (%>%), et lorsqu’on les applique
sur des sous-ensembles de données.
Supposons qu’on veut créer un sous-ensemble de
airquality pour le mois de juin, et ensuite convertir la
variable de la température en degrés Celsius. on peut écrire les
opérations en ordre d’exécutions et les relier à l’aide du “pipe”
%>% :
library(dplyr)
##
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
##
## filter, lag
## The following objects are masked from 'package:base':
##
## intersect, setdiff, setequal, union
juin_C <- airquality %>%
filter(Month == 6) %>%
mutate(Temp_C = (Temp-32)*(5/9))
head(juin_C)
## Ozone Solar.R Wind Temp Month Day Temp_C
## 1 NA 286 8.6 78 6 1 25.55556
## 2 NA 287 9.7 74 6 2 23.33333
## 3 NA 242 16.1 67 6 3 19.44444
## 4 NA 186 9.2 84 6 4 28.88889
## 5 NA 220 8.6 85 6 5 29.44444
## 6 NA 264 14.3 79 6 6 26.11111
Les fonctions dplyr suivantes nous permettent de séparer
nos jeu de données en groupes distincts sur lesquels on peut exécuter
des opérations individuelles, comme des fonctions d’aggrégation et de
sommaire:
group_by(): regrouper le jeu de données par un facteur
pour les opérations en aval (comme summarise)summarise(): créer un sommaire de variables au sein de
groupes distincts dans un jeu de données en utilisant des fonctions
d’aggrégation (e.g. min(), max(),
mean(), etc…)Ces deux verbes fournissent la structure requise pour la stratégie
Séparer-Appliquer-Combiner (“Split-Apply-Combine”) originalement
introduite dans le paquet plyr, l’ancêtre de
dplyr.
Utilisons ces deux fonctions pour générer un sommaire du jeu de
données airquality qui montre la température moyenne et
l’écart type pour chaque mois:
> mois_moy <- airquality %>%
group_by(Month) %>%
summarise(mean_temp = mean(Temp),
sd_temp = sd(Temp))
mois_moy
Source: local data frame [5 x 3]
Month mean_temp sd_temp
(int) (dbl) (dbl)
1 5 65.54839 6.854870
2 6 79.10000 6.598589
3 7 83.90323 4.315513
4 8 83.96774 6.585256
5 9 76.90000 8.355671
En plus des fonctions que nous avons explorées aujourd’hui,
dplyr offre d’autres fonctions forts utiles nous permettant
de fusionner des tableau de données, avec une syntaxe relativement
simple :
left_join()right_join()inner_join()anti_join()Ces fonctions vont au-delà du matériel d’introduction dans cet atelier, mais ils offrent des fonctionnalités pouvant être très utiles pour des manipulations de données plus complexes. ————————————————————————
Bref, pour les statistique et les visualisations! Voici, un example:
On veut visualiser le jeu de données airquality et on
s’interesse à la variation des variables Ozone,
Temp et Wind avec le temps. On sait déjà
comment utiliser la fonction select() pour retenir
uniquement les colonnes requises et on sait déjà comment rassembler les
colonnes avec pivot_longer(). Cependant, pour le figure,
les colonnes Month et Day seraient plus utiles
dans un format de date. Donc, on peut faire toutes ces manipulations
ensemble:
library(lubridate) # paquet pour transformer les dates!
##
## Attaching package: 'lubridate'
## The following objects are masked from 'package:base':
##
## date, intersect, setdiff, union
air.plot <- airquality %>%
select(c(Ozone, Temp, Wind, Month, Day)) %>%
mutate(Date = lubridate::make_date("1973", Month, Day)) %>%
pivot_longer(cols = c("Ozone", "Wind", "Temp"),
names_to = c("variable"),
values_to = c("value"))
Maintenant, on est capable de visualiser les données:
library(ggplot2)
ggplot(air.plot,
aes(x = Date, y = value, col = variable)) +
geom_point() +
geom_smooth()
## `geom_smooth()` using method = 'loess' and formula = 'y ~ x'
ggplot2Que voulez-vous communiquer? Quelle est la meilleure façon de représenter vos données et votre message?
De nombreux paquets R peuvent nous aider à créer des figures. Nous
allons nous concentrer sur ggplot2 car: 1.
ggplot2 vous
permet de créer de beaux graphiques personnalisables;
2. ggplot2
implémente la grammaire des graphiques, qui est un système fiable pour
construire des graphiques.
3. Il existe de nombreuses
extensions pour ajouter encore plus de fonctionnalités à
ggplot2, ce qui permet une multitude d’applications.
Quelques exemples:
Commençons par les bases! La librairie ggplot2 est basée sur la Grammaire des Graphiques (GG), qui est un cadre pour la visualisation de données qui décompose chaque élément d’un graphique en composants individuels, créant ainsi des couches distinctes. En utilisant le système GG, nous pouvons construire des graphiques étape par étape pour des résultats flexibles et personnalisables.
Les couches GG ont des noms spécifiques que vous verrez tout au long de l’atelier:
Image adaptée de The Grammar of Graphics.
Pour créer un ggplot, les couches de données et de
mapping sont des exigences de base, tandis que
les autres couches sont destinées à une configuration supplémentaire.
Les couches ‘non requises’ sont toujours importantes à considérer,
mais vous serez en mesure de générer un graphique de base sans
celles-ci.
Conditions de base pour générer un `ggplot’.
Voici une décomposition de chaque couche Grammaire des Graphiques et des arguments courants pour chacune d’elles qui peut vous servir de référence:
dplyr pour préparer les données
pour un format optimal pour la visualisation.x, y: position le long des axes x et
ycolour: la couleur des géométries selon les
donnéesfill: la couleur intérieure des géométriesgroup: à quel groupe appartient une géométrieshape: la forme des pointslinetype: le type de ligne utilisé (pleine, pointillée,
etc.)size: la taille des points ou des lignesalpha: la transparence des géométriesgeom_point() : diagramme de dispersiongeom_line() : lignes reliant des points par une valeur
croissante de xgeom_path() : lignes reliant des points dans l’ordre
d’apparitiongeom_boxplot() : diagramme en boîte (boxplot) pour les
variables catégoriquesgeom_bar() : diagrammes à barres pour un axe des x
catégoriquegeom_histogram() : histogramme pour l’axe des x
continugeom_violin() : kernel de distribution de la dispersion
des donnéesgeom_smooth() : ligne de lissage en fonction des
donnéesfacet_wrap() ou facet_grid() pour de
petits multiplescoord_cartesian pour fixer des limitescoord_polar pour les graphiques circulairescoord_map pour différentes projections
cartographiquespalmerpenguinsEssayons maintenant de visualiser des données! Nous allons utiliser
le jeu de données palmerpenguins.
Art par Allison Horst.
Ce jeu de données contient des mesures morphologiques pour trois espèces de pingouins observées sur trois îles de l’archipel Palmer, en Antarctique. Ces données ont été recueillies de 2007 à 2009 par la Dre Kristen Gorman dans le cadre du programme de recherche écologique à long terme de la station Palmer, qui fait partie du réseau américain de recherche écologique à long terme.
Artwork by Allison Horst.
Regardons les variables de l’ensemble de données des pingouins :
library(palmerpenguins)
data(penguins) # regardons les données des pingouins !
Art par Allison Horst.
Notez que l’espèce, l’île et le sexe (species,
island, et sex) sont des facteurs, qui seront
importantes pour regrouper les données avec des couleurs, des formes,
etc. dans ggplot2. Il y a ensuite 2 variables numériques
(mesures du bec représentées dans l’image), et deux variables entières
(longueur des nageoires et masse corporelle). Les données ont également
une petite composante temporelle (year), s’étendant de 2007
à 2009.
Notez: Les graphiques plus complexes dans les ggplot2 nécessitent que les données soient en format long.
Quelles sont quelques questions scientifiques auxquelles nous pourrions vouloir répondre avec ce jeu de données? Voici quelques exemples:
Comment pouvons-nous répondre graphiquement à ces questions avec
ggplot2?
Nous devrions explorer comment certaines de ces données sont structurées par espèce!
# Explorons comment nos données sont structurées par espèce
ggplot(data = penguins, # Données
aes(x = bill_length_mm, # Valeurs X
y = bill_depth_mm, # Valeurs Y
col = species)) + # Esthétique (mettre une couleur par espèce)
geom_point(size = 5, alpha = 0.8) + # Points
geom_smooth(method = "lm") + # Régression linéaire
labs(title = "Relationship between bill length and depth\nfor different penguin species", # Title
x = "Bill length (mm)", # titre de l'axe des X
y = "Bill depth (mm)", # titre de l'axe des Y
col = "Species") + # Légende pour les couleurs dans aes(col = species)
theme_classic() + # Utiliser un thème propre
theme(title = element_text(size = 18, face = "bold"),
text = element_text(size = 16))
En différenciant les espèces, on peut voir qu’il existe une relation assez cohérente entre la longueur et la profondeur du bec entre les espèces (pentes similaires), mais que les gammes de ces variables sont différentes (les regroupements sont clairement indiqués par les couleurs). Les pingouins Adélie ont tendance à avoir une longueur de bec plus petite mais une profondeur de bec assez grande, alors que l’inverse est vrai pour les pingouins Gentoo.
ggplot() par couchesComme nous l’avons vu, un graphique est constitué de différentes
couches, combinées ensemble pour communiquer visuellement des
informations dans nos données. Construisons un graphique
ggplot étape par étape en ajoutant une couche à la
fois.
# Couche 1: Données
ggplot(data = penguins)
# Sans autre information, vos données ne seront pas visualisées.
Dans ggplot2, l’esthétique est un groupe de paramètres
qui spécifie les données à afficher et la manière de les afficher. Ici,
nous demandons à R de tracer
longueur_de_bill_mm sur l’axe x et
profondeur_de_bill_mm sur l’axe y. Nous
n’avons pas encore dit à R comment nous voulons
représenter les données, donc nos données ne seront pas encore
tracées.
# Prochaine couche: esthétiques
# Ici, nous disons à R de tracer la longueur sur l'axe des x, et la profondeur sur l'axe des y.
# mais nous n'avons toujours pas dit à R comment nous voulons que ces données soient représentées...
ggplot(data = penguins,
aes(x = bill_length_mm,
y = bill_depth_mm))
# Vous voyez ? Nos variables sont maintenant assignées aux axes x et y,
# mais rien n'est encore tracé.
Les objets géométriques, ou geoms, déterminent la
représentation visuelle de vos données. Nous pouvons commencer par
représenter nos points de données sous la forme d’un nuage de points,
pour voir comment la profondeur et la longueur du bec sont liées l’une à
l’autre.
# Prochaine couche(s): géométries
ggplot(data = penguins,
aes(x = bill_length_mm,
y = bill_depth_mm)) + # Utilisez le signe + pour ajouter chaque couche
geom_point() # La couche geom détermine le type de tracé que nous utilisons.
# geom_point() trace les données sous forme de points !
Notez que vous pouvez ajouter plusieurs geoms dans un
seul graphique. Par exemple, nous pouvons ajouter une ligne sur ce
graphique pour montrer une valeur seuil, ou ajouter une régression
linéaire. Pour l’instant, gardons la simplicité!
Maintenant que le jeu de données est représenté graphiquement, nous
pouvons personnaliser le graphique pour clarifier le message ou ajouter
des informations supplémentaires. Les facettes sont un moyen populaire
de diviser un graphique en plusieurs fenêtres selon une catégorie de
données, afin de différencier visuellement les groupes. Nous pouvons
explorer ce graphique différemment si nous utilisons
facet_wrap() pour créer des ‘facettes’ séparées en fonction
de nos groupes d’espèces:
# Prochaine couche(s): customizations!
# Les facettes divisent un graphique en fenêtres séparées selon une certaine catégorie dans les données.
ggplot(data = penguins,
aes(x = bill_length_mm,
y = bill_depth_mm)) +
geom_point() +
facet_wrap(vars(species)) # Cela divise le graphique en trois fenêtres : une par espèce.
Nous pouvons également ajuster l’échelle de nos axes dans le graphique lui-même, plutôt que de transformer les données. Supposons que nous souhaitions étudier la relation entre les mesures du bec sur une échelle de \(log_{10}\).
ggplot(data = penguins,
aes(x = bill_length_mm,
y = bill_depth_mm)) +
geom_point() +
facet_wrap(vars(species)) +
# ceci transforme les coordonnées des axes avec log10()
coord_trans(x = "log10", y = "log10")
Pour terminer, nous pouvons également personnaliser le thème du
graphique, qui comprend son arrière-plan, les quadrillages et d’autres
caractéristiques visuelles du graphique. Supposons que nous n’aimons pas
le fond gris par défaut de ggplot2 (nous ne serions pas les seuls!).
Nous pouvons utiliser theme_bw() pour produire un rendu
visuel plus attrayant. Nous discuterons des thèmes dans le chapitre
@ref(theme)!
ggplot(data = penguins,
aes(x = bill_length_mm,
y = bill_depth_mm,
col = species)) +
geom_point() +
facet_wrap(vars(species)) +
coord_trans(x = "log10", y = "log10") +
# ce thème produit un rendu visuel plus attrayant
theme_bw()
Il est maintenant temps d’essayer de construire votre propre graphique ! Créez un ggplot pour répondre aux questions suivantes:
Équipe 1:
1. Y a-t-il une relation entre la longueur des becs et la longueur des nageoires des pingouins?
2. La longueur des becs augmente-t-elle avec celle des nageoires?
Paramètres à prendre en compte pour répondre à cette question:
| données | géométrie | valeurs x | valeurs y |
|---|---|---|---|
| penguins | geom_point | bill_length_mm | flipper_length_mm |
Équipe 2:
1. Y a-t-il une relation entre le sex et le poids corporelle?
2. Est-ce que la relation est pareil dans les trois especes?
Paramètres à prendre en compte pour répondre à cette question:
| données | géométrie | valeurs x | valeurs y |
|---|---|---|---|
| penguins | geom_boxplot | sex | body_mass_g |
Noubliez pas l’Esthétique (mettre une couleur par espèce), si utile!
Essayez de manipuler le jeu de données penguins_raw.csv
afin d’arriver au format de jeu de données penguins.csv.
Les operations de tidyr et dplyr seraient
utiles…
Généralement, votre meilleure source d’information sera votre moteur de recherche préféré!
Voici quelques conseils pour l’utiliser efficacement:
(N’oubliez pas l’ongle Help dans RStudio)